package com.xy.biz.xd.service.impl;

import com.xy.biz.fd.domain.DocumentPermissions;
import com.xy.biz.fd.domain.utils.DocumentPropertyUtils;
import com.xy.biz.mc.client.MessagePushClient;
import com.xy.biz.mc.domain.Message;
import com.xy.biz.mc.domain.consts.MessageTypeConstant;
import com.xy.biz.mc.domain.req.MessagePushRequest;
import com.xy.biz.uc.client.UserClient;
import com.xy.biz.uc.domain.dto.UserDTO;
import com.xy.biz.uc.domain.req.ListUserGroupByIdsRequest;
import com.xy.biz.xd.domain.bo.*;
import com.xy.biz.xd.domain.converter.DocumentFlowBorrowAndPrintAndDropConverter;
import com.xy.biz.xd.domain.req.ApplyDocumentFlowBorrowRequest;
import com.xy.biz.xd.domain.req.ReleaseDocumentFlowNewRequest;
import com.xy.biz.xd.manager.*;
import com.xy.biz.xd.service.DocumentFlowBorrowService;
import com.xy.lang.domain.Result;
import com.xy.lang.util.ResultUtils;
import com.xy.tool.context.UserContextHolder;
import com.xy.tool.gid.service.GidService;
import com.xy.tool.json.JsonUtils;
import org.activiti.engine.task.Task;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

import static com.xy.biz.fd.domain.DocumentPermissions.PREVIEW;
import static com.xy.biz.fd.domain.DocumentPermissions.VISIBLE;
import static com.xy.biz.xd.domain.bo.DocumentFlowConstants.*;
import static com.xy.biz.xd.domain.bo.DocumentReleaseBO.*;
import static java.util.stream.Collectors.toList;

@Deprecated
@Service
public class DocumentFlowBorrowServiceImpl extends AbstractDocumentFlowBorrowAndPrintAndDropServiceImpl implements DocumentFlowBorrowService {

    @Autowired
    private GidService gidService;
    @Autowired
    private DocumentFlowServiceSupport documentFlowServiceSupport;

    @Autowired
    private DocumentFlowBorrowManager documentFlowBorrowManager;

    @Autowired
    DocumentFlowBorrowAndPrintAndDropManager documentFlowBorrowAndPrintAndDropManager;

    @Autowired
    private DocumentFlowManager documentFlowManager;

    @Autowired
    private DocumentFlowHandleManager documentFlowHandleManager;

    @Autowired
    private DocumentReleaseManager documentReleaseManager;

    @Autowired
    private MessagePushClient messagePushClient;

    @Autowired
    private UserClient userClient;

    private String type = "借阅";

    @Override
    protected String getType() {
        return type;
    }

    @Transactional
    @Override
    public Result<?> saveDocumentFlow(ApplyDocumentFlowBorrowRequest request) {
        DocumentFlowBorrowAndPrintAndDropBO documentFlowBorrowBO = DocumentFlowBorrowAndPrintAndDropConverter.toBO(request);
        buildBorrowDocumentFlowBO(documentFlowBorrowBO);

        Task task = documentFlowServiceSupport.startFirstTask(documentFlowBorrowBO, PROCESS_COMMON_FLOW, request.getNextHandleUserId());

        String foreignKey = task.getProcessInstanceId();
        documentFlowBorrowBO.setForeignKey(foreignKey);
        int row = documentFlowBorrowAndPrintAndDropManager.saveDocumentFlowBorrowAndPrintAndDrop(documentFlowBorrowBO);
        if (row > 0) {
            //定义消息内容
            Message build = Message.builder()
                    .type(MessageTypeConstant.TYPE_FLOW)
                    .data(1)
                    .path(MessageTypeConstant.FLOW_LIST)
                    .remark("借阅流程-文件审核")
                    .build();
            //发送消息
            messagePushClient.send(MessagePushRequest.builder()
                    .data(JsonUtils.toJson(build).getBytes())
                    .dataType(0)
                    .expiredSeconds(0L)
                    .toId(request.getNextHandleUserId())
                    .offlineFlag(true).build());
        }

        return Result.success();
    }

    @Transactional
    @Override
    public Result<?> releaseDocumentFlow(ReleaseDocumentFlowNewRequest request) {
        LocalDateTime now = LocalDateTime.now();
        DocumentFlowBO documentFlowBO = documentFlowManager.getDocumentFlow(request.getDocumentFlowId());
        DocumentFlowHandleBO documentFlowHandleBO = DocumentFlowHandleBO.build(documentFlowBO, UserContextHolder.getUserId(), PHASE_RELEASE, HANDLE_RESULT_ACCEPT, request.getOpinion());
        documentFlowHandleManager.saveAllDocumentFlowHandle(Arrays.asList(documentFlowHandleBO));
        documentFlowBO.setDocumentId(request.getDocumentId());
        documentFlowManager.updateDocumentFlow(documentFlowBO);
        documentFlowServiceSupport.finishLastTask(documentFlowBO);
        List<Long> receiveUserGroupIdList = request.getReceiveUserGroupIdList();
        List<Long> receiveUserIdList = request.getReceiveUserIdList();
        if (!CollectionUtils.isEmpty(receiveUserGroupIdList) && !CollectionUtils.isEmpty(receiveUserIdList)) {
            Set<Long> ids = ResultUtils.get(userClient.listUserByUserGroup(ListUserGroupByIdsRequest.builder().groupIds(request.getReceiveUserGroupIdList()).build())).stream().map(UserDTO::getUserId).collect(Collectors.toSet());
            receiveUserIdList = receiveUserIdList.stream().filter(item -> !ids.contains(item)).collect(toList());
        }
        List<DocumentReleaseBO> documentReleaseBOList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(receiveUserIdList)) {
            for (Long receiveUserId : receiveUserIdList) {
                //documentReleaseBOList.add(buildDocumentReleaseBO(documentFlowBO, receiveUserId, RECEIVE_TYPE_USER, now, STATUS_RELEASE, DocumentPermissions.addPermission(VISIBLE, PREVIEW)));
            }
        }
        if (!CollectionUtils.isEmpty(receiveUserGroupIdList)) {
            for (Long receiveUserGroupId : receiveUserGroupIdList) {
                //documentReleaseBOList.add(buildDocumentReleaseBO(documentFlowBO, receiveUserGroupId, RECEIVE_TYPE_USER_GROUP, now, STATUS_RELEASE, DocumentPermissions.addPermission(VISIBLE, PREVIEW)));
            }
        }
        documentReleaseBOList = documentReleaseBOList.stream()
                .peek(d -> {
                    d.setFlowType(documentFlowBO.getFlowType());
                    d.setEffectDate(request.getEffectDate());
                    d.setDocumentFlowId(documentFlowBO.getDocumentFlowId());
                    //给文档设置等级和属性
                    String property = null;// TODO DocumentCodeFormatValidationUtils.getDocumentProperty(d.getDocumentCode());
                    d.setDocumentLevel(DocumentPropertyUtils.getLevelNum(property));
                    d.setDocumentProperty(property);
                })
                .collect(Collectors.toList());
        if (!CollectionUtils.isEmpty(documentReleaseBOList)) {
            documentReleaseManager.saveAllDocumentRelease(documentReleaseBOList);
        }

        DocumentFlowBorrowBO borrowBO = DocumentFlowBorrowBO.builder()
                .createTime(LocalDateTime.now())
                .deleteFlag(0)
                .documentFlowId(request.getDocumentFlowId())
                .revertTime(LocalDateTime.now().plusDays(3))
                .tenantId(0L)
                .updateTime(LocalDateTime.now())
                .build();
        documentFlowBorrowManager.saveDocumentFlowBorrow(borrowBO);
        return Result.success();
    }

    private void buildBorrowDocumentFlowBO(DocumentFlowBorrowAndPrintAndDropBO documentFlowBorrowBO) {
        LocalDateTime now = LocalDateTime.now();

        documentFlowBorrowBO.setDocumentFlowId(gidService.generate());
        documentFlowBorrowBO.setFlowType(FLOW_TYPE_BORROW);
        documentFlowBorrowBO.setPhase(PHASE_CONTENT_AUDIT);
        documentFlowBorrowBO.setDocumentId(0L);
        documentFlowBorrowBO.setTenantId(UserContextHolder.getTenantId());
        documentFlowBorrowBO.setCreateUserId(UserContextHolder.getUserId());
        documentFlowBorrowBO.setCreateTime(now);
        documentFlowBorrowBO.setUpdateTime(now);

        DocumentFlowHandleBO.build(documentFlowBorrowBO, UserContextHolder.getUserId(), PHASE_APPLY, HANDLE_RESULT_ACCEPT, documentFlowBorrowBO.getReason());
    }

}
